package cs.rsa.ts14.foxtrot.app;

import cs.rsa.ts14.foxtrot.CategoryReportImpl;
import cs.rsa.ts14.foxtrot.LineTypeClassifierStrategyImpl;
import cs.rsa.ts14.foxtrot.NullReportBuilder;
import cs.rsa.ts14.framework.LineSequenceState;
import cs.rsa.ts14.framework.LineTypeClassifierStrategy;
import cs.rsa.ts14.framework.ReportBuilder;
import cs.rsa.ts14.framework.TimesagLineProcessor;
import cs.rsa.ts14.golf.statemachine.InitialState;
import cs.rsa.ts14.hotel.TransportModeOverviewBuilder;
import cs.rsa.ts14.kilo.WeekOverviewBuilder;
import cs.rsa.ts14.standard.StandardTimesagLineProcessor;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;

class Builder {
    private final File file;
    private LineTypeClassifierStrategy classifier;
    private LineSequenceState sequenceState;
    private ReportBuilder reportBuilder = null;
    private String reportType;
    private TimesagLineProcessor timesagProcessor;
    private PrintStream outputStream;
    private TimesagLines tsLines;

    public Builder(File file) {
        reportType = "null";
        outputStream = System.out;
        this.file = file;
    }

    public Builder(TimesagLines lines) {
        reportType = "null";
        outputStream = System.out;
        file = null;
        tsLines = lines;
    }

    private static ReportBuilder createBuilder(String reportTypeString) {
        if (reportTypeString.toLowerCase().equals("c"))
            return new CategoryReportImpl();
        if (reportTypeString.toLowerCase().equals("w"))
            return new WeekOverviewBuilder();
        if (reportTypeString.toLowerCase().equals("t"))
            return new TransportModeOverviewBuilder();

        return new NullReportBuilder();
    }

    public FoxyTimesag build() throws IOException {
        if(tsLines == null)
            tsLines = new TimesagFileLines(file);

        if(timesagProcessor == null) {
            if (reportBuilder == null)
                reportBuilder = createBuilder(reportType);

            if (classifier == null)
                classifier = new LineTypeClassifierStrategyImpl();

            if (sequenceState == null)
                sequenceState = new InitialState();

            timesagProcessor = new StandardTimesagLineProcessor(classifier, reportBuilder, sequenceState);
        }

        return new FoxyTimesag(this);
    }

    public Builder setReportType(String reportType) {
        this.reportType = reportType;
        return this;
    }

    public TimesagLineProcessor getTimesagProcessor() {
        return timesagProcessor;
    }

    public PrintStream getOutputStream() {
        return outputStream;
    }

    public Builder setOutputStream(PrintStream ps) {
        outputStream = ps;
        return this;
    }

    public TimesagLines getTimesagLines() throws IOException {
        return tsLines;
    }

    public Builder setTimesagLineProcessor(TimesagLineProcessor tsp) {
        timesagProcessor = tsp;
        return this;
    }

    public Builder setReportBuilder(ReportBuilder reportBuilder) {
        this.reportBuilder = reportBuilder;
        return this;
    }
}
